//
//  BoxManViewController.m
//  BoxMan
//
//  Created by wang yiping on 11-2-15.
//  Copyright 2011 app. All rights reserved.
//

#import "BoxManViewController.h"
#define BLOCKOBJECTWALL '#'              // This is the wall
#define BLOCKOBJECTBLANKSPACE ' '        // This is the blankSpace
#define BLOCKOBJECTSNOWMAN '@'           // This is the snowMan
#define BLOCKOBJECTTARGET '+'            // This is the target
#define BLOCKOBJECTSNOWBALL '*'          // This is the snowBall
#define BLOCKOBJECTSNOWMANINTARGET '&'   // This is the snowManInTarget
#define BLOCKOBJECTSNOWBALLINTARGET 'O'  // This is the snowBallInTarget
#define BLOCKOBJECTUNKNOWSPACE '-'       // This is the unknowSpace


@interface BoxManViewController(ImageUtility)
- (void)initResourceImage;
- (UIImage *)getSubImageWithRect:(CGRect)rect;
- (UIImage *)getBlankSpace;
- (UIImage *)getSnowBall;
- (UIImage *)getSnowMan;
- (UIImage *)getSnowBallInTarget;
- (UIImage *)getTarget;
- (UIImage *)getSnowManInTarget;
- (UIImage *)getWall;
- (UIImage *)getUnkonwSpace;
@end

@interface BoxManViewController(MazeUtility)
- (NSString *)getMaze:(NSInteger) mazeIndex;
- (void)layoutMaze:(NSInteger)mazeIndex;
- (MazeObjectView *)buildMazeBlockAtRect:(CGRect)rect WithFlag:(char)flag;
- (MazeObjectView *)findMazeObjectViewAtPosition:(CGPoint)position;
@end
@interface BoxManViewController(MazeExplore)
- (BOOL)canSnowManWalkTo:(CGPoint)position;
@end

@interface BoxManViewController(TestFunction)
- (void) test;
@end

@implementation BoxManViewController
@synthesize resourceImage;


/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
*/


// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
	[super loadView];
	[self initResourceImage];
	[self layoutMaze:0];
	/*
	UIImage * blankSpace       = [self getSubImage:image WithRect:CGRectMake(0, 0, 50, 50)];
	UIImage * snowBall         = [self getSubImage:image WithRect:CGRectMake(50, 0, 50, 50)];
	UIImage * snowMan          = [self getSubImage:image WithRect:CGRectMake(100, 0, 50, 50)];
	UIImage * snowBallInTarget = [self getSubImage:image WithRect:CGRectMake(150, 0, 50, 50)];
	UIImage * target           = [self getSubImage:image WithRect:CGRectMake(200, 0, 50, 50)];
	UIImage * snowManInTarget  = [self getSubImage:image WithRect:CGRectMake(250, 0, 50, 50)];
	UIImage * wall             = [self getSubImage:image WithRect:CGRectMake(300, 0, 50, 50)];
	UIImage * unKnowSpace      = [self getSubImage:image WithRect:CGRectMake(350, 0, 50, 50)];
	
	*/
	//[self test];
	
	
}

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}
#pragma mark TestFunction methods
- (void)test {
	
}
#pragma mark MazeUtility methods
- (NSString *)getMaze:(NSInteger)mazeIndex {
	NSLog(@"mazeIndex:%d",mazeIndex);
	return [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%d",mazeIndex] ofType:@"maze"]];
}

- (void)layoutMaze:(NSInteger)mazeIndex {
	NSString * mazeString = [self getMaze:0];
	
	NSArray * mazeLines = [mazeString componentsSeparatedByString:@"\n"];

	int mazeHeight = [mazeLines count];
	int mazeWidth  = [[mazeLines objectAtIndex:0] length];
	
	nowMazeSize.width = mazeWidth;
	nowMazeSize.height = mazeHeight;
	
	for (int i = 0 ; i < mazeHeight ; i  ++ ) {
		if ([[mazeLines objectAtIndex:i] length] < mazeWidth) {
			continue;
		}
		NSLog(@"line:%d %@",i,[mazeLines objectAtIndex:i]);
		for (int j = 0 ; j < mazeWidth ; j ++ ) {
			NSLog(@"col:%d %c",j,[[mazeLines objectAtIndex:i] characterAtIndex:j]);
			nowMazeState[i][j] = [[mazeLines objectAtIndex:i] characterAtIndex:j];
			CGRect rect = CGRectMake(i * 50.0 , j * 50.0 , 50 , 50 );
			MazeObjectView * blockView = [self buildMazeBlockAtRect:rect WithFlag:nowMazeState[i][j]];
			[[self view] addSubview:blockView];
			if (nowMazeState[i][j] == BLOCKOBJECTSNOWMAN || nowMazeState[i][j] == BLOCKOBJECTSNOWMANINTARGET) {
				snowMan = blockView;
			}
			[blockView release];
		}
	}
}

- (MazeObjectView *)buildMazeBlockAtRect:(CGRect)rect WithFlag:(char)flag {
	UIImage * image;
	switch (flag) {
		case '#': // This is the wall
			image = [self getWall];
			break;
		case ' ': // This is the blankSpace
			image = [self getBlankSpace];
			break;
		case '@': // This is the snowMan
			image = [self getSnowMan];
			snowManNowLocation = CGPointMake(rect.origin.x/50.0, rect.origin.y/50.0);
			break;
		case '+': // This is the target
			image = [self getTarget];
			break;
		case '*': // This is the snowBall
			image = [self getSnowBall];
			break;
		case '&': // This is the snowManInTarget
			image = [self getSnowManInTarget];
			snowManNowLocation = CGPointMake(rect.origin.x/50.0, rect.origin.y/50.0);
			break;
		case 'O': // This is the snowBallInTarget
			image = [self getSnowBallInTarget];
			break;
		case '-': // This is the unknowSpace
			image = [self getUnkonwSpace];
			break;
		default:
			break;
	}
	
	MazeObjectView *imageView = [[MazeObjectView alloc] initWithImage:image];
	[imageView setDelegate:self];
	[imageView setObjectPosition:CGPointMake(rect.origin.x / 50.0, rect.origin.y / 50.0)];
	[imageView setFrame:rect];
	[imageView setObjectType:flag];
	[imageView retain];
	
	return imageView;
	//[image release];
}
- (MazeObjectView *)findMazeObjectViewAtPosition:(CGPoint)position {
	MazeObjectView * mv = nil;
	
	for (MazeObjectView *view in [[self view] subviews]) {
		if (view.objectPosition.x == position.x && view.objectPosition.y == position.y) {
			//Find it;
			mv = view;
			break;
		}
	}
	return mv;
}
#pragma mark ImageUtility methods
- (void)initResourceImage {
	resourceImage = [UIImage imageNamed:@"Map.bmp"];
}
- (UIImage *)getSubImageWithRect:(CGRect)rect {
	CGImageRef subImageRef = CGImageCreateWithImageInRect([self resourceImage].CGImage, rect);
	CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));
	UIGraphicsBeginImageContext(smallBounds.size);
	CGContextRef context = UIGraphicsGetCurrentContext();
	CGContextDrawImage(context, smallBounds, subImageRef);
	UIImage * smallImage = [UIImage imageWithCGImage:subImageRef];
	UIGraphicsEndImageContext();
	return smallImage;
}
- (UIImage *)getBlankSpace {
	return [self getSubImageWithRect:CGRectMake(0, 0, 50, 50)];
}
- (UIImage *)getSnowBall {
	return [self getSubImageWithRect:CGRectMake(50, 0, 50, 50)];
}
- (UIImage *)getSnowMan {
	return [self getSubImageWithRect:CGRectMake(100, 0, 50, 50)];
}
- (UIImage *)getSnowBallInTarget {
	return [self getSubImageWithRect:CGRectMake(150, 0, 50, 50)];
}
- (UIImage *)getTarget {
	return [self getSubImageWithRect:CGRectMake(200, 0, 50, 50)];
}
- (UIImage *)getSnowManInTarget {
	return [self getSubImageWithRect:CGRectMake(250, 0, 50, 50)];
}
- (UIImage *)getWall {
	return [self getSubImageWithRect:CGRectMake(300, 0, 50, 50)];
}
- (UIImage *)getUnkonwSpace {
	return [self getSubImageWithRect:CGRectMake(350, 0, 50, 50)];
}
#pragma mark MazeObjectViewDelegate methods
- (void)mazeObjectWasTapped:(MazeObjectView *)mv {
	/*
	if (mv.objectType == BLOCKOBJECTWALL || mv.objectType == BLOCKOBJECTSNOWMAN || mv.objectType == BLOCKOBJECTUNKNOWSPACE) {
		//
	}
	 */
	if (snowManAutoWalkingTimer == nil) {
		if (mv.objectType == BLOCKOBJECTBLANKSPACE || mv.objectType == BLOCKOBJECTTARGET) {
			//Find a way from original position to this new position
			CGPoint pos = CGPointMake(mv.objectPosition.x, mv.objectPosition.y);
			
			if ([self canSnowManWalkTo:pos]){
				snowManInPathPos = 0;
				snowManAutoWalkingTimer = [NSTimer scheduledTimerWithTimeInterval:(10.0 / 60.0)
																		   target:self 
																		 selector:@selector(snowManAutoWalkingTimerFired:) 
																		 userInfo:mv 
																		  repeats:YES];
			}
		}
		else if (mv.objectType == BLOCKOBJECTSNOWBALL || mv.objectType == BLOCKOBJECTSNOWBALLINTARGET)
		{
			// only if snowMan is close to this block
			MazeObjectView * snowBallNewPosOldView = nil;
			MazeObjectView * snowBallNewPosNewView = nil;
			MazeObjectView * snowManNewPosNewView  = nil;
			MazeObjectView * snowManOldPosNewView  = nil;
			
			if (((snowMan.objectPosition.x + 1) == mv.objectPosition.x) && (snowMan.objectPosition.y == mv.objectPosition.y)) {
				// Then do something
				CGPoint snowBallNewPos = CGPointMake((snowMan.objectPosition.x + 2), snowMan.objectPosition.y);
				snowBallNewPosOldView = [self findMazeObjectViewAtPosition:snowBallNewPos];
				
				if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTBLANKSPACE) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALL;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALL];
				}
				else if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTTARGET) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALLINTARGET;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALLINTARGET];
				}
			}
			else if (((snowMan.objectPosition.x - 1) == mv.objectPosition.x) && (snowMan.objectPosition.y == mv.objectPosition.y)) {
				// Then do something
				CGPoint snowBallNewPos = CGPointMake((snowMan.objectPosition.x - 2), snowMan.objectPosition.y);
				snowBallNewPosOldView = [self findMazeObjectViewAtPosition:snowBallNewPos];
				
				if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTBLANKSPACE) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALL;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALL];
				}
				else if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTTARGET) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALLINTARGET;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALLINTARGET];
				}
			}
			else if ((snowMan.objectPosition.x == mv.objectPosition.x) && ((snowMan.objectPosition.y + 1) == mv.objectPosition.y)) {
				// Then do something
				CGPoint snowBallNewPos = CGPointMake(snowMan.objectPosition.x, (snowMan.objectPosition.y + 2));
				snowBallNewPosOldView = [self findMazeObjectViewAtPosition:snowBallNewPos];
				
				if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTBLANKSPACE) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALL;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALL];
				}
				else if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTTARGET) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALLINTARGET;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALLINTARGET];
				}
			}
			else if ((snowMan.objectPosition.x == mv.objectPosition.x) && ((snowMan.objectPosition.y - 1)== mv.objectPosition.y)) {
				// Then do something
				CGPoint snowBallNewPos = CGPointMake(snowMan.objectPosition.x, (snowMan.objectPosition.y - 2));
				snowBallNewPosOldView = [self findMazeObjectViewAtPosition:snowBallNewPos];
				
				if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTBLANKSPACE) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALL;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALL];
				}
				else if (nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] == BLOCKOBJECTTARGET) {
					nowMazeState[(int)(snowBallNewPos.x)][(int)(snowBallNewPos.y)] = BLOCKOBJECTSNOWBALLINTARGET;
					snowBallNewPosNewView = [self buildMazeBlockAtRect:[snowBallNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWBALLINTARGET];
				}
			}
			
			if (snowBallNewPosNewView) {
				
				if (nowMazeState[(int)(mv.objectPosition.x)][(int)(mv.objectPosition.y)] == BLOCKOBJECTSNOWBALL) {
					nowMazeState[(int)(mv.objectPosition.x)][(int)(mv.objectPosition.y)] = BLOCKOBJECTSNOWMAN;
					snowManNewPosNewView = [self buildMazeBlockAtRect:[mv frame] WithFlag:BLOCKOBJECTSNOWMAN];
				}
				else if (nowMazeState[(int)(mv.objectPosition.x)][(int)(mv.objectPosition.y)] == BLOCKOBJECTSNOWBALLINTARGET) {
					nowMazeState[(int)(mv.objectPosition.x)][(int)(mv.objectPosition.y)] = BLOCKOBJECTSNOWMANINTARGET;
					snowManNewPosNewView = [self buildMazeBlockAtRect:[mv frame] WithFlag:BLOCKOBJECTSNOWMANINTARGET];
				}
				
				if (nowMazeState[(int)(snowMan.objectPosition.x)][(int)(snowMan.objectPosition.y)] == BLOCKOBJECTSNOWMAN) {
					nowMazeState[(int)(snowMan.objectPosition.x)][(int)(snowMan.objectPosition.y)] = BLOCKOBJECTBLANKSPACE;
					snowManOldPosNewView = [self buildMazeBlockAtRect:[snowMan frame] WithFlag:BLOCKOBJECTBLANKSPACE];
				}
				else if (nowMazeState[(int)(snowMan.objectPosition.x)][(int)(snowMan.objectPosition.y)] == BLOCKOBJECTSNOWMANINTARGET) {
					nowMazeState[(int)(snowMan.objectPosition.x)][(int)(snowMan.objectPosition.y)] = BLOCKOBJECTTARGET;
					snowManOldPosNewView = [self buildMazeBlockAtRect:[snowMan frame] WithFlag:BLOCKOBJECTTARGET];
				}
				
				[mv removeFromSuperview];
				//[mv release];
				[snowMan removeFromSuperview];
				//[snowMan release];
				[snowBallNewPosOldView removeFromSuperview];
				//[snowBallNewPosOldView release];
				
				
				[[self view] addSubview:snowBallNewPosNewView];
				[[self view] addSubview:snowManNewPosNewView];
				[[self view] addSubview:snowManOldPosNewView];
				snowMan = snowManNewPosNewView;
				[snowBallNewPosNewView release];
				[snowManOldPosNewView release];
			}
		}
	}
	else {
		// Add to touch list?? Or now do nothing!
		NSLog(@"Touch proceed unfinished!");
	}

	
}
#pragma mark snowManAutoWalkingTimerFired methods
- (void)snowManAutoWalkingTimerFired:(NSTimer *)timer {
	snowManInPathPos++;
	if (snowManInPathPos == pathLookedUpLength) {
		[snowManAutoWalkingTimer invalidate];
		snowManAutoWalkingTimer = nil;
		return;
	}
	CGPoint newPos = snowManWalkPath[snowManInPathPos];
	MazeObjectView * snowManNewPosOldView = nil;
	MazeObjectView * snowManOldPosNewView = nil;
	MazeObjectView * snowManNewPosNewView = nil;
	
	for (MazeObjectView *view in [[self view] subviews]) {
		if (view.objectPosition.x == newPos.x && view.objectPosition.y == newPos.y) {
			//Find it;
			snowManNewPosOldView = view;
			break;
		}
	}
	
	// Save Information
	char originalObjectType = snowMan.objectType;
	char newObjectType      = nowMazeState[(int)(snowManNewPosOldView.objectPosition.x)][(int)(snowManNewPosOldView.objectPosition.y)];
	
	
	if (originalObjectType == BLOCKOBJECTSNOWMAN) {
		// Space
		nowMazeState[(int)(snowMan.objectPosition.x)][(int)(snowMan.objectPosition.y)] = BLOCKOBJECTBLANKSPACE;
		snowManOldPosNewView = [self buildMazeBlockAtRect:[snowMan frame] WithFlag:BLOCKOBJECTBLANKSPACE];
	}
	else if (originalObjectType == BLOCKOBJECTSNOWMANINTARGET)
	{
		//Target
		nowMazeState[(int)(snowMan.objectPosition.x)][(int)(snowMan.objectPosition.y)] = BLOCKOBJECTTARGET;
		snowManOldPosNewView = [self buildMazeBlockAtRect:[snowMan frame] WithFlag:BLOCKOBJECTTARGET];
	}
	if (newObjectType == BLOCKOBJECTTARGET) {
		//SnowManInTarget
		nowMazeState[(int)(snowManNewPosOldView.objectPosition.x)][(int)(snowManNewPosOldView.objectPosition.y)] = BLOCKOBJECTSNOWMANINTARGET;
		snowManNewPosNewView = [self buildMazeBlockAtRect:[snowManNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWMANINTARGET];
	}
	else if (newObjectType == BLOCKOBJECTBLANKSPACE)
	{
		//SnowMan
		nowMazeState[(int)(snowManNewPosOldView.objectPosition.x)][(int)(snowManNewPosOldView.objectPosition.y)] = BLOCKOBJECTSNOWMAN;
		snowManNewPosNewView = [self buildMazeBlockAtRect:[snowManNewPosOldView frame] WithFlag:BLOCKOBJECTSNOWMAN];
	}
	[snowMan removeFromSuperview];
	[snowManNewPosOldView removeFromSuperview];
	//[snowMan release];
	//[snowManNewPosOldView release];
	
	snowMan = snowManNewPosNewView;
	[[self view] addSubview:snowManNewPosNewView];
	[[self view] addSubview:snowManOldPosNewView];
	[snowManNewPosNewView release];
	[snowManOldPosNewView release];
}
#pragma mark MazeExplore methods
- (BOOL)canSnowManWalkTo:(CGPoint)position {
	//NSArray *maze = [[NSArray alloc] init];
	
	//NSArray *maze = [[NSArray alloc] initWithArray:nowMazeState];
	
	char lookupQueueMazeState[400][20][20];
	CGPoint lookupQueueSnowManState[400];
	int     lookupQueueSnowManStatePathRecord[400];
	
	//init maze
	for (int i = 0 ; i < nowMazeSize.height ; i  ++ ) {
		for (int j = 0 ; j < nowMazeSize.width ; j ++ ) {
			char block = nowMazeState[i][j];
			if ( block == BLOCKOBJECTTARGET || block == BLOCKOBJECTSNOWMAN || block == BLOCKOBJECTSNOWMANINTARGET ) {
				lookupQueueMazeState[0][i][j] = BLOCKOBJECTBLANKSPACE;
			}
			else if ( block == BLOCKOBJECTSNOWBALLINTARGET)
			{
				lookupQueueMazeState[0][i][j] = BLOCKOBJECTSNOWBALL;
			}
			else {
				lookupQueueMazeState[0][i][j] = block;
			}
		}
	}
	
	NSInteger start;
	NSInteger end;
	start = 0;
	end = 1;
	
	lookupQueueSnowManState[start] = snowManNowLocation;
	lookupQueueSnowManStatePathRecord[start] = -1;
	lookupQueueMazeState[start][(int)(snowManNowLocation.x)][(int)(snowManNowLocation.y)] = BLOCKOBJECTWALL;
	BOOL isOK = NO;
	while (start != end) {
		if (end > 399) {
			NSLog(@"This cause Error hanppe!");
		}
		CGPoint snowManNowLoc = lookupQueueSnowManState[start];
		
		int posX = (int)(snowManNowLoc.x);
		int posY = (int)(snowManNowLoc.y);
		int newPosX;
		int newPosY;
		
		// Try right;
		if ((posY + 1) < nowMazeSize.width) {
			newPosX = posX;
			newPosY = posY + 1;
			
			char rightBlockObject = lookupQueueMazeState[start][newPosX][newPosY];
			if (rightBlockObject == BLOCKOBJECTBLANKSPACE) {
				
				//can go
				lookupQueueSnowManState[end] = CGPointMake(newPosX, newPosY);
				lookupQueueSnowManStatePathRecord[end] = start;
				//init new maze
				
				for (int i = 0 ; i < nowMazeSize.height ; i ++ ) {
					for (int j = 0 ; j < nowMazeSize.width ; j ++ ) {
						lookupQueueMazeState[end][i][j] = lookupQueueMazeState[start][i][j];
					}
				}
				lookupQueueMazeState[end][newPosX][newPosY] = BLOCKOBJECTWALL;
				end ++;
				if (newPosX == position.x && newPosY == position.y) {
					// O'I see you!
					isOK = YES;
					break;
				}
			}
		}
		// Try down:
		if ((posX + 1) < nowMazeSize.height) {
			newPosX = posX + 1;
			newPosY = posY;
			
			char rightBlockObject = lookupQueueMazeState[start][newPosX][newPosY];
			if (rightBlockObject == BLOCKOBJECTBLANKSPACE) {
				//can go
				lookupQueueSnowManState[end] = CGPointMake(newPosX, newPosY);
				lookupQueueSnowManStatePathRecord[end] = start;
				//init new maze
				for (int i = 0 ; i < nowMazeSize.height ; i ++ ) {
					for (int j = 0 ; j < nowMazeSize.width ; j ++ ) {
						lookupQueueMazeState[end][i][j] = lookupQueueMazeState[start][i][j];
					}
				}
				lookupQueueMazeState[end][newPosX][newPosY] = BLOCKOBJECTWALL;
				end ++;
				if (newPosX == position.x && newPosY == position.y) {
					// O'I see you!
					isOK = YES;
					break;
				}
			}
		}
		// Try up;
		if ((posX - 1) >= 0) {
			newPosX = posX - 1;
			newPosY = posY;
			
			char rightBlockObject = lookupQueueMazeState[start][newPosX][newPosY];
			if (rightBlockObject == BLOCKOBJECTBLANKSPACE) {
				//can go
				lookupQueueSnowManState[end] = CGPointMake(newPosX, newPosY);
				lookupQueueSnowManStatePathRecord[end] = start;
				//init new maze
				for (int i = 0 ; i < nowMazeSize.height ; i ++ ) {
					for (int j = 0 ; j < nowMazeSize.width ; j ++ ) {
						lookupQueueMazeState[end][i][j] = lookupQueueMazeState[start][i][j];
					}
				}
				lookupQueueMazeState[end][newPosX][newPosY] = BLOCKOBJECTWALL;
				end ++;
				if (newPosX == position.x && newPosY == position.y) {
					// O'I see you!
					isOK = YES;
					break;
				}
			}
		}
		// Try left;
		if ((posY - 1) >= 0) {
			newPosX = posX;
			newPosY = posY - 1;
			
			char rightBlockObject = lookupQueueMazeState[start][newPosX][newPosY];
			if (rightBlockObject == BLOCKOBJECTBLANKSPACE) {
				//can go
				lookupQueueSnowManState[end] = CGPointMake(newPosX, newPosY);
				lookupQueueSnowManStatePathRecord[end] = start;
				//init new maze
				for (int i = 0 ; i < nowMazeSize.height ; i ++ ) {
					for (int j = 0 ; j < nowMazeSize.width ; j ++ ) {
						lookupQueueMazeState[end][i][j] = lookupQueueMazeState[start][i][j];
					}
				}
				lookupQueueMazeState[end][newPosX][newPosY] = BLOCKOBJECTWALL;
				end ++;
				if (newPosX == position.x && newPosY == position.y) {
					// O'I see you!
					isOK = YES;
					break;
				}
			}
		}
		start ++;
	}
	if (isOK) {
		// Coloct path information
		int c = 0;
		for (int i = end - 1; i >= 0 ; i = lookupQueueSnowManStatePathRecord[i]) {
			snowManWalkPath[c] = lookupQueueSnowManState[i];
			c ++;
		}
		// Reserver it!
		int p = 0;
		int q = c - 1;
		while (p < q) {
			CGPoint tmp;
			tmp = snowManWalkPath[p];
			snowManWalkPath[p] = snowManWalkPath[q];
			snowManWalkPath[q] = tmp;
			p ++;
			q --;
		}
		pathLookedUpLength = c;
	}
	return isOK;
}
@end
